// CPU.cpp : Defines the entry point for the console application.
 
#include "stdafx.h"
#pragma warning(disable : 4786)
#include <cstdio>  
#include <Windows.h>
#pragma   comment(lib,"psapi.lib")
#include <psapi.h>
#include   <time.h>
#include <stdlib.h> 
typedef long           int64_t;
typedef unsigned long    uint64_t;
 #define M 1024*1024
#include <iostream> 
#include "vector"
#include "map"
#include "string"
#define TIME_LEN 64 
 
using namespace std;

 static uint64_t file_time_2_utc(const FILETIME* ftime)
{
    LARGE_INTEGER li;
 
    li.LowPart = ftime->dwLowDateTime;
    li.HighPart = ftime->dwHighDateTime;
    return li.QuadPart;
}
 
 static int get_processor_number()
{
    SYSTEM_INFO info;
    GetSystemInfo(&info);
    return (int)info.dwNumberOfProcessors;
}
 
int get_cpu_usage(int pid)
{  
	
  
    static int processor_count_ = -1;
     static int64_t last_time_ = 0;
    static int64_t last_system_time_ = 0;
 
    FILETIME now;
    FILETIME creation_time;
    FILETIME exit_time;
    FILETIME kernel_time;
    FILETIME user_time;
    int64_t system_time;
    int64_t time;
    int64_t system_time_delta;
    int64_t time_delta;
 
    int cpu = -1;
 
    if(processor_count_ == -1)
    {
        processor_count_ = get_processor_number();
    }
 
    GetSystemTimeAsFileTime(&now);
 
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
    if (!GetProcessTimes(hProcess, &creation_time, &exit_time, &kernel_time, &user_time))
    { 
	//	cout<<"first if"<<endl;
        return 0;
    }
    system_time = (file_time_2_utc(&kernel_time) + file_time_2_utc(&user_time)) 
        / processor_count_;  
    time = file_time_2_utc(&now);
 
    if ((last_system_time_ == 0) || (last_time_ == 0))
    {
	//	cout<<"2nd if"<<endl;
        last_system_time_ = system_time;
        last_time_ = time;
        return 0;
    }
 
    system_time_delta = system_time - last_system_time_;
    time_delta = time - last_time_;
 
    if (time_delta == 0){
	//	cout<<"3rd if"<<endl;
		return 0;
    }
       
 
    cpu = (int)((system_time_delta * 100 + time_delta / 2) / time_delta);
    last_system_time_ = system_time;
    last_time_ = time;

    CloseHandle( hProcess );
	//cout<<"pid: "<<pid<<"---"<<cpu<<endl;
    return cpu;
}

int get_memory_usage( int processID ){
	HANDLE hProcess;
	PROCESS_MEMORY_COUNTERS pmc;
	hProcess = OpenProcess(  PROCESS_QUERY_INFORMATION |	PROCESS_VM_READ,  FALSE, processID );
	if (NULL == hProcess)  return 0;
	int memory = -1; 
	GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)); 
	CloseHandle( hProcess );
	return (pmc.WorkingSetSize )/(M ) ;
}
 string getCurrentTime(){
	 char current_time[64];
     time_t t = time(0);
     
    strftime( current_time, 64, "%Y-%m-%d %H:%M:%S",localtime(&t) );
    return  (current_time);

 }

 typedef vector<int> PROCESS;
 //exe sleep ie=[pid,pid....] firefox=[pid....]
 map<string, PROCESS> make_map(int argc, const char *argv[])  {
     map<string, PROCESS> processs;
    for( int i=2; i< argc; ++i){
        
        string line = argv[i] ;
        string name = line.substr(0,line.find("="));

        //cout<<"line: "<< line<< endl;
        int begin=line.find("[");
        int end=line.find(",", begin);
        vector<int> temvec ;
    
        if( end < 0 ) {
            string str_int = line.substr(begin+1, line.find("]")-begin-1);
            int kk=atoi(str_int.c_str()) ;
            temvec.push_back(kk) ;
				
             
        }
        else{
            while( 0 < end ){
                string str_int = line.substr(begin + 1 ,end-begin-1);
                int kk=atoi(str_int.c_str()) ;
                temvec.push_back(kk) ;
                
                begin = end ;
                end=line.find(",", begin+1);
            } //else
            int kk= atoi(line.substr(begin+1, line.find("]")-begin-1).c_str());
            temvec.push_back(kk) ;
		
        }//if
        processs[name]=temvec  ;
        //cout<<endl;
    }
    return processs ;
 }
 // cup ie=[123,456] firefox=[234]
 /*
  * date,ie-cpu,ie-memory,firefox-cpu,fire-memory
  */
 void compute_map( map<string, PROCESS> process){
	 cout<<getCurrentTime()<<",";

     map<string, PROCESS>::iterator it;
	 int loop=0;
     for( it= process.begin(); it != process.end(); ++it ){
        PROCESS tem = it->second;
		int cpu =0, memory = 0;
        for( int i=0; i<  tem.size(); ++i){
			if( tem[i] <= 0 ) continue ;
			cpu += get_cpu_usage( tem[i] );
			memory += get_memory_usage ( tem[i] );
        }
	 
	 	if( loop!=0) cout<<",";
		loop++;
	 	cout<<cpu<<","<<memory;
     }
	 cout<<endl;
 }
 void get_head_line(map<string, PROCESS> process ){
	 map<string, PROCESS>::iterator it;
	 cout<<"============================"<<endl;
	for( it= process.begin(); it != process.end(); it++ ){
		cout<<"========" << (it->first) <<"\t";
	//	cout<<(it->first)<<"_cpu\t"<<(it->first)<<"_memory\t";
		PROCESS tem = it->second;
		for( int i=0; i< tem.size(); ++i){
			if( tem[i] <= 0 ) continue ;
			cout<<" "<< tem[i];
       }
		cout<<"========" <<endl;
	}
	cout<<"============================"<<endl;
	
	cout<<endl<<endl;
	
	cout<<"date,";
	for( it= process.begin(); it != process.end(); it++ ){
		cout<< (it->first) <<"_cpu,"<<(it->first)<<"_memory,";
	}
	cout<<endl;
 }
//exe sleep ie=[pid,pid....] firefox=[pid....]
int main(int argc, const char *argv[])   
{ 
	map<string, PROCESS> args = make_map(argc,argv);
	get_head_line(args );
	int i=atoi(argv[1]);	 
	 while(1)   
    {  
		 Sleep(i);
 		 compute_map (args);
		//cout<<endl;
	 }
   return 0;
}